﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DotNetCore.CAP.Internal;
using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.HandInvoice.Dto;
using NP.BPMReportPlatform.Todo.Dto;
using NP.BPMReportPlatform.Utils;
using NP.BPMReportPlatform.ZH.Dto;
using NP.Enterprise.Utils.Http;
using SqlSugar;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.Finance
{
    public class FinanceService : BPMReportPlatformAppService, IFinanceService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly INPRestHttpHelper _helper;
        private readonly string _esbUrl;

        public FinanceService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, INPRestHttpHelper helper, IConfiguration configuration)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _helper = helper;
            _esbUrl = configuration["Nippon:ESB:ESBCommApi"];
        }
        #region 保理平台ukey及账户申请报表
        public async Task<PagedResultDto<GetFactoringPlatformOutput>> GetAllAsync(GetFactoringPlatformInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x => x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId));

            //返回结果
            return new PagedResultDto<GetFactoringPlatformOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetFactoringPlatformOutput>> ExportAsync(GetFactoringPlatformInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }


        private ISugarQueryable<GetFactoringPlatformOutput> GetQueryable(GetFactoringPlatformInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }
            var listQueryable = _db.Queryable<FactoringPlatformHeader, BusinessProcessesNew>(
                     (x,  b) => new JoinQueryInfos( JoinType.Left, x.InstanceNumber == b.InstanceId))
                .WhereIF(!input.IsQueryAll, x => x.AddUserId.Equals(currentUserId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber),x => x.InstanceNumber == input.InstanceNumber)
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, b) => SqlFunc.ContainsArray(input.OrderStatus.ToArray(), b.ProcessStatusCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), x => x.AddUserName.Contains(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,
                    x => x.AddTime >= input.StartCreationTime && x.AddTime <= input.EndCreationTime)
                .Select((x, b) => new GetFactoringPlatformOutput()
                {
                    InstanceNumber = x.InstanceNumber,
                    CreateTime = x.AddTime,
                    AddUserName = x.AddUserName,
                    OrderStatus = b.ProcessStatusName,
                    SaleRegion = x.SaleRegion,
                    CustomerManagerName = x.CustomerManagerName,
                    CustomerNo = x.CustomerNo,
                    CustomerName = x.CustomerName,
                    AnnualSales = x.AnnualSales,
                    BusinessVolume1 = x.BusinessVolume1,
                    BusinessVolume2 = x.BusinessVolume2,
                    IsBA = x.IsBA,
                    BATime = x.BATime,
                    IsZY = x.IsZY,
                    IsBZS = x.IsBZS,
                    IsCDBLFY = x.IsCDBLFY,
                    FactoringRate =x.FactoringRate,
                    FactoringPlatform = x.FactoringPlatform,
                    FactoringBank = x.FactoringBank,
                    AreaReq = x.AreaReq,
                    OtherAreaReq =x.OtherAreaReq,
                    BankAccountReq = x.BankAccountReq,
                    UkeySetter = x.UkeySetter,
                    UkeySetter1 = x.UkeySetter1,
                    OtherBankReq =x.OtherBankReq,
                    BankLinkInfo = x.BankLinkInfo,
                    CompanyCode =x .CompanyCode,
                    CompanyName = x.CompanyName,
                    BankAccount = x.BankAccount,
                    BankName =x.BankName,
                    UkeyCode =x.UkeyCode,
                    UkeyCode1 = x.UkeyCode1,
                }).MergeTable().Distinct().OrderBy(ins => ins.CreateTime, OrderByType.Desc);
            return listQueryable;
        }
        #endregion

        #region CBS待办 查询数据
        public async Task<PagedResultDto<ItemsItem>> GetAllAsync(GetTodoInput input)
        {
            input.Sorting = "";
            if (input.PageIndex < 1)
            {
                input.PageIndex = 1;
            }
            var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
            input.AdUser = currentUserDto?.UserLoginId;
            input.CurrentUserId = currentUserDto?.WorkNumber;
            input.IsOld = false;
            if(string.IsNullOrWhiteSpace(input.Topic))
            {
                var list = new List<ItemsItem>();
                //查询两次，1标题"月付款申请"结尾的；
                input.Topic =  "月付款申请" ;
                var headers1 = new Dictionary<string, string>
                {
                    {"requestId", Guid.NewGuid().ToString()},
                    {"trackId", Guid.NewGuid().ToString()},
                    {"sourceSystem", "BPMNEW"},
                    {"serviceName", "S_XXX_WXApprove_GetToDoListAsync_S"} // 获取token
                };
                var result1 = await _helper.ESBPostAsync<GetTodoOutput>(_esbUrl, input, headers1);

                if (result1.Code != 200)
                {
                    return new PagedResultDto<ItemsItem>()
                    {
                        Items = Array.Empty<ItemsItem>(),
                        TotalCount = 0
                    };
                }
                foreach (var item in result1.Result.Items)
                {
                    if (item.TOPIC.EndsWith("月付款申请")||item.TOPIC.Contains("转背汇票"))
                    {
                        list.Add(item);
                    }
                }
                //查询两次,2标题中包含"转背汇票"的
                input.Topic = "转背汇票";
                var headers2 = new Dictionary<string, string>
                {
                    {"requestId", Guid.NewGuid().ToString()},
                    {"trackId", Guid.NewGuid().ToString()},
                    {"sourceSystem", "BPMNEW"},
                    {"serviceName", "S_XXX_WXApprove_GetToDoListAsync_S"} // 获取token
                };
                var result2 = await _helper.ESBPostAsync<GetTodoOutput>(_esbUrl, input, headers2);

                if (result2.Code != 200)
                {
                    return new PagedResultDto<ItemsItem>()
                    {
                        Items = Array.Empty<ItemsItem>(),
                        TotalCount = 0
                    };
                }
                foreach (var item in result2.Result.Items)
                {
                    if (item.TOPIC.EndsWith("月付款申请") || item.TOPIC.Contains("转背汇票"))
                    {
                        list.Add(item);
                    }
                }
                return new PagedResultDto<ItemsItem>()
                {
                    Items = list,
                    TotalCount = list.Count
                };
            }
            else
            {
                var headers = new Dictionary<string, string>
                {
                    {"requestId", Guid.NewGuid().ToString()},
                    {"trackId", Guid.NewGuid().ToString()},
                    {"sourceSystem", "BPMNEW"},
                    {"serviceName", "S_XXX_WXApprove_GetToDoListAsync_S"} // 获取token
                };
                var result = await _helper.ESBPostAsync<GetTodoOutput>(_esbUrl, input, headers);

                if (result.Code != 200)
                {
                    return new PagedResultDto<ItemsItem>()
                    {
                        Items = Array.Empty<ItemsItem>(),
                        TotalCount = 0
                    };
                }
                var list = new List<ItemsItem>();
                foreach (var item in result.Result.Items)
                {
                    if (item.TOPIC.EndsWith("月付款申请"))
                    {
                        list.Add(item);
                    }
                }
                return new PagedResultDto<ItemsItem>()
                {
                    Items = list,
                    TotalCount = list.Count
                };
            }   
        }
        #endregion

        #region 客户应收余额调整申请报表
        public async Task<PagedResultDto<GetKHYSYETZOutput>> GetAllAsync(GetKHYSYETZInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x => x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId));

            //返回结果
            return new PagedResultDto<GetKHYSYETZOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetKHYSYETZOutput>> ExportAsync(GetKHYSYETZInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }


        private ISugarQueryable<GetKHYSYETZOutput> GetQueryable(GetKHYSYETZInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }
            var listQueryable = _db.Queryable<KHYSYETZHeader, BusinessProcessesNew, KHYSYETZDetail>(
                   (x, bu, m) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == bu.InstanceId, JoinType.Left, x.InstanceNumber == m.InstanceNumber))
               .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber),
                   (x, bu) => x.InstanceNumber.Contains(input.InstanceNumber))
               .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), x => x.AddUserName.Equals(input.AddUserName))
               .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, bu) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), bu.ProcessStatusCode))
               .WhereIF(!string.IsNullOrWhiteSpace(input.Company), x => x.CompanyCode.Contains(input.Company) || x.CompanyName.Contains(input.Company))
               .WhereIF(!string.IsNullOrWhiteSpace(input.InfoControl), x => x.InfoControl.Contains(input.InfoControl))
               .WhereIF(!string.IsNullOrWhiteSpace(input.ProfitCentre), x => x.ProfitCentre.Contains(input.ProfitCentre))
               .WhereIF(!string.IsNullOrWhiteSpace(input.CostCentre), x => x.CostCentre.Contains(input.CostCentre)|| x.CostCentreName.Contains(input.CostCentre))
               .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.AddTime >= input.StartCreationTime && x.AddTime.AddDays(-1) <= input.EndCreationTime)
               .Select((x, bu, m) =>
                   new GetKHYSYETZOutput()
                   {
                       InstanceNumber = x.InstanceNumber,
                       CreateTime = bu.StartTime,
                       AddUserName = x.AddUserName,
                       OrderStatus = bu.ProcessStatusName,
                       CompanyCode = x.CompanyCode,
                       CompanyName = x.CompanyName,
                       InfoControl = x.InfoControl,
                       CustomerType = x.CustomerType,
                       AdjustSubject = x.AdjustSubject,
                       AmountTotal = x.AmountTotal,
                       BusinessGroup = x.BusinessGroup,
                       SalesRegion = x.SalesRegion,
                       CostCentre = x.CostCentre,
                       CostCentreName = x.CostCentreName,
                       ProfitCentre = x.ProfitCentre,
                       Reason = x.Reason,
                       SyncResult = x.SyncResult,
                       SyncMessage = x.SyncMessage,
                       SortNo = m.SortNo.ToString(),
                       CustomerNo = m.CustomerNo,
                       CustomerName = m.CustomerName,
                       Industry = m.Industry,
                       BusinessNo = m.BusinessNo,
                       BusinessDesc = m.BusinessDesc,
                       AdjustType = m.AdjustType,
                       AdjustAmount = m.AdjustAmount,
                       TaxRate = m.TaxRate,
                       NoTaxAmount = m.NoTaxAmount,
                       TaxAmount = m.TaxAmount
                   }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc);
           
            return listQueryable;
        }
        #endregion
    }
}